[IA64] Introduce machine vector for platform specific fixups for dom0.
authorAlex Williamson <alex.williamson@hp.com>
Mon, 18 Jun 2007 19:50:42 +0000 (13:50 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Mon, 18 Jun 2007 19:50:42 +0000 (13:50 -0600)
This is required to map SN2 specific registers to dom0.

Signed-off-by: Jes Sorensen <jes@sgi.com>
xen/arch/ia64/xen/Makefile
xen/arch/ia64/xen/dom_fw_sn2.c [new file with mode: 0644]
xen/arch/ia64/xen/dom_fw_utils.c
xen/include/asm-ia64/linux-xen/asm/machvec.h
xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h

index a0966e2a2711cf5a48849b2d2bff82d33b830748..f1e748816ab881e0e8ce721855850897f8725edd 100644 (file)
@@ -10,6 +10,7 @@ obj-y += dom_fw_common.o
 obj-y += dom_fw_dom0.o
 obj-y += dom_fw_domu.o
 obj-y += dom_fw_utils.o
+obj-y += dom_fw_sn2.o
 obj-y += fw_emul.o
 obj-y += hpsimserial.o
 obj-y += hypercall.o
diff --git a/xen/arch/ia64/xen/dom_fw_sn2.c b/xen/arch/ia64/xen/dom_fw_sn2.c
new file mode 100644 (file)
index 0000000..93da9b6
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  Xen domain0 platform firmware fixups for sn2
+ *  Copyright (C) 2007 Silicon Graphics Inc.
+ *       Jes Sorensen <jes@sgi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <xen/config.h>
+#include <xen/acpi.h>
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <xen/nodemask.h>
+
+#include <asm/dom_fw.h>
+#include <asm/dom_fw_common.h>
+#include <asm/dom_fw_dom0.h>
+#include <asm/dom_fw_utils.h>
+
+#include <asm/sn/arch.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/shub_mmr.h>
+
+#define SWAP_NASID(n, x)       ((x & ~NASID_MASK) | NASID_SPACE(n))
+
+int __init
+sn2_dom_fw_init(domain_t *d,
+               struct xen_ia64_boot_param *bp,
+               struct fw_tables *tables)
+{
+       int node;
+       short nasid;
+       unsigned long shubid, shubpicam, shubpiowrite;
+
+       printk("SN2 mapping specific registers to dom0\n");
+
+       assign_domain_mach_page(d, LOCAL_MMR_OFFSET | SH_RTC, PAGE_SIZE,
+                               ASSIGN_nocache);
+
+       if (is_shub1()) {
+               /* 0x110060000 */
+               shubid = SH1_GLOBAL_MMR_OFFSET + (SH1_SHUB_ID & PAGE_MASK);
+               /* 0x120050000 */
+               shubpicam = SH1_GLOBAL_MMR_OFFSET +
+                       (SH1_PI_CAM_CONTROL & PAGE_MASK);
+               /* 0x120070000 */
+               shubpiowrite = SH1_GLOBAL_MMR_OFFSET +
+                       (SH1_PIO_WRITE_STATUS_0 & PAGE_MASK);
+
+               for_each_online_node(node) {
+                       nasid = cnodeid_to_nasid(node);
+                       shubid = SWAP_NASID(nasid, shubid);
+                       shubpicam = SWAP_NASID(nasid, shubpicam);
+                       shubpiowrite = SWAP_NASID(nasid, shubpiowrite);
+
+                       assign_domain_mach_page(d, shubid, PAGE_SIZE,
+                                               ASSIGN_nocache);
+                       assign_domain_mach_page(d, shubpicam, PAGE_SIZE,
+                                               ASSIGN_nocache);
+                       assign_domain_mach_page(d, shubpiowrite, PAGE_SIZE,
+                                               ASSIGN_nocache);
+               }
+
+               /* map leds */
+               assign_domain_mach_page(d, LOCAL_MMR_OFFSET |
+                                       SH1_REAL_JUNK_BUS_LED0,
+                                       PAGE_SIZE, ASSIGN_nocache);
+               assign_domain_mach_page(d, LOCAL_MMR_OFFSET |
+                                       SH1_REAL_JUNK_BUS_LED1,
+                                       PAGE_SIZE, ASSIGN_nocache);
+               assign_domain_mach_page(d, LOCAL_MMR_OFFSET |
+                                       SH1_REAL_JUNK_BUS_LED2,
+                                       PAGE_SIZE, ASSIGN_nocache);
+               assign_domain_mach_page(d, LOCAL_MMR_OFFSET |
+                                       SH1_REAL_JUNK_BUS_LED3,
+                                       PAGE_SIZE, ASSIGN_nocache);
+       } else
+               panic("Unable to build EFI entry for SHUB 2 MMR\n");
+
+       return 0;
+}
index 1369b05560e99e325667d98eddab1db032c05f6c..941bacae6a904168061a37d990e3bf761252dbed 100644 (file)
@@ -292,6 +292,13 @@ int dom_fw_setup(domain_t * d, unsigned long bp_mpa, unsigned long maxmem)
                        xfree(fw_tables);
                        return ret;
                }
+
+               ret = platform_fw_init(d, bp, fw_tables);
+               if (ret < 0) {
+                       xfree(fw_tables);
+                       return ret;
+               }
+
                if (sizeof(*fw_tables) +
                    fw_tables->num_mds * sizeof(fw_tables->efi_memmap[0]) >
                    fw_tables_size) {
index fd1f883b6331a9f2c50350307981ffbbc9656d7e..56a3d25ebe0ae6cd887daaa7b79391761ece2876 100644 (file)
@@ -191,6 +191,15 @@ machvec_noop_pci_legacy_write (struct pci_bus *bus, u16 port, u32 val, u8 size)
        panic("%s() called", __FUNCTION__);
        return 0;
 }
+
+typedef int ia64_mv_fw_init_t (void *d, void *bp, void *tables);
+
+static inline int
+machvec_noop_platform_fw_init (void *d, void *bp, void *tables)
+{
+       return 0;
+}
+
 #endif
 
 extern void machvec_setup (char **);
@@ -254,6 +263,9 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *);
 #  define platform_readw_relaxed        ia64_mv.readw_relaxed
 #  define platform_readl_relaxed        ia64_mv.readl_relaxed
 #  define platform_readq_relaxed        ia64_mv.readq_relaxed
+#ifdef XEN
+#  define platform_fw_init      ia64_mv.fw_init
+#endif
 # endif
 
 /* __attribute__((__aligned__(16))) is required to make size of the
@@ -302,8 +314,12 @@ struct ia64_machine_vector {
        ia64_mv_readw_relaxed_t *readw_relaxed;
        ia64_mv_readl_relaxed_t *readl_relaxed;
        ia64_mv_readq_relaxed_t *readq_relaxed;
+#ifdef XEN
+       ia64_mv_fw_init_t *fw_init;
+#endif
 } __attribute__((__aligned__(16))); /* align attrib? see above comment */
 
+#ifdef XEN
 #define MACHVEC_INIT(name)                     \
 {                                              \
        #name,                                  \
@@ -346,7 +362,53 @@ struct ia64_machine_vector {
        platform_readw_relaxed,                 \
        platform_readl_relaxed,                 \
        platform_readq_relaxed,                 \
+       platform_fw_init,                       \
 }
+#else
+#define MACHVEC_INIT(name)                     \
+{                                              \
+       #name,                                  \
+       platform_setup,                         \
+       platform_cpu_init,                      \
+       platform_irq_init,                      \
+       platform_send_ipi,                      \
+       platform_timer_interrupt,               \
+       platform_global_tlb_purge,              \
+       platform_tlb_migrate_finish,            \
+       platform_dma_init,                      \
+       platform_dma_alloc_coherent,            \
+       platform_dma_free_coherent,             \
+       platform_dma_map_single,                \
+       platform_dma_unmap_single,              \
+       platform_dma_map_sg,                    \
+       platform_dma_unmap_sg,                  \
+       platform_dma_sync_single_for_cpu,       \
+       platform_dma_sync_sg_for_cpu,           \
+       platform_dma_sync_single_for_device,    \
+       platform_dma_sync_sg_for_device,        \
+       platform_dma_mapping_error,                     \
+       platform_dma_supported,                 \
+       platform_local_vector_to_irq,           \
+       platform_pci_get_legacy_mem,            \
+       platform_pci_legacy_read,               \
+       platform_pci_legacy_write,              \
+       platform_inb,                           \
+       platform_inw,                           \
+       platform_inl,                           \
+       platform_outb,                          \
+       platform_outw,                          \
+       platform_outl,                          \
+       platform_mmiowb,                        \
+       platform_readb,                         \
+       platform_readw,                         \
+       platform_readl,                         \
+       platform_readq,                         \
+       platform_readb_relaxed,                 \
+       platform_readw_relaxed,                 \
+       platform_readl_relaxed,                 \
+       platform_readq_relaxed,                 \
+}
+#endif
 
 extern struct ia64_machine_vector ia64_mv;
 extern void machvec_init (const char *name);
@@ -494,5 +556,10 @@ extern ia64_mv_dma_supported               swiotlb_dma_supported;
 #ifndef platform_readq_relaxed
 # define platform_readq_relaxed        __ia64_readq_relaxed
 #endif
+#ifdef XEN
+#ifndef platform_fw_init
+# define platform_fw_init      machvec_noop_platform_fw_init
+#endif
+#endif
 
 #endif /* _ASM_IA64_MACHVEC_H */
index 4af484a7d9341ef066755c5a4b1dc7f83e195514..0574a85c3cd9c796bad3450792528d05090a41e8 100644 (file)
@@ -71,6 +71,9 @@ extern ia64_mv_migrate_t              sn_migrate;
 extern ia64_mv_setup_msi_irq_t         sn_setup_msi_irq;
 extern ia64_mv_teardown_msi_irq_t      sn_teardown_msi_irq;
 #endif
+#ifdef XEN
+extern ia64_mv_fw_init_t               sn2_dom_fw_init;
+#endif
 
 
 /*
@@ -161,6 +164,10 @@ extern ia64_mv_teardown_msi_irq_t  sn_teardown_msi_irq;
 #endif
 #endif
 
+#ifdef XEN
+#define platform_fw_init               sn2_dom_fw_init
+#endif
+
 #include <asm/sn/io.h>
 
 #endif /* _ASM_IA64_MACHVEC_SN2_H */